import { tokenize } from "./tokenize.js";

/**
 * @description 解析模板字符串，生成模板AST
 * @param {*} str
 * @returns
 */
export function parse(str) {
  /* 对模板字符串标记化，得到tokens（对模板AST的描述） */
  const tokens = tokenize(str);
  // console.log('🚀 ~ parse ~ tokens ====> ', tokens)
  /* 模板AST的根节点Root */
  const root = {
    type: "Root",
    children: [],
  };
  /* 创建elementStack栈，起初只有root */
  const elementStack = [root];

  /* 开启一个while循环扫描 tokens，直到所有 Token 都被扫描完成为止 */
  while (tokens.length) {
    /* 获取当前栈顶节点作为父节点parent */
    const parent = elementStack[elementStack.length - 1];
    /* 当前扫描的token */
    const token = tokens.shift();

    /* 匹配当前token */
    switch (token.type) {
      case "tag":
        /* 当type为tag时，创建一个Element类型的AST节点 */
        const element = {
          type: "Element",
          tag: token.name,
          children: [],
        };

        /* 将其添加到栈顶节点（父节点）的children中 */
        parent.children.push(element);
        /* 将生成的Element 类型的 AST 节点压入栈中 */
        elementStack.push(element);
        break;
      case "text":
        /* 当type为text时，创建一个Text类型的AST节点 */
        const text = {
          type: "Text",
          content: token.content,
        };
        /* 将其添加到栈顶节点（父节点）的children中 */
        parent.children.push(text);
        break;
      case "tagEnd":
        /* 当type为tagEnd时，将栈顶元素弹出 */
        elementStack.pop();
        break;
    }
  }

  return root;
}
